]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
st-scroll-view: Add :overlay-scrollbars property
authorFlorian Müllner <fmuellner@gnome.org>
Thu, 21 Feb 2013 21:30:09 +0000 (22:30 +0100)
committerFlorian Müllner <fmuellner@gnome.org>
Fri, 22 Feb 2013 09:57:50 +0000 (10:57 +0100)
If enabled, scrollbars take away from the allocation given to the
view's content. This is usually preferrable to painting the bars on
top of the content, but there are exceptions, for instance when the
content needs to be centered with regard to the view as a whole.
Add a :overlay-scrollbars property to account for those cases.

https://bugzilla.gnome.org/show_bug.cgi?id=694261

src/st/st-scroll-view.c
src/st/st-scroll-view.h
tests/interactive/scroll-view-sizing.js

index e452900d34fb22ca46feb2f6f93d9289df0cec1f..9ea394b05a154c7b34bfa5be8d82801a481604d2 100644 (file)
@@ -101,6 +101,7 @@ struct _StScrollViewPrivate
   gboolean      row_size_set : 1;
   gboolean      column_size_set : 1;
   guint         mouse_scroll : 1;
+  guint         overlay_scrollbars : 1;
   guint         hscrollbar_visible : 1;
   guint         vscrollbar_visible : 1;
 };
@@ -115,6 +116,7 @@ enum {
   PROP_HSCROLLBAR_VISIBLE,
   PROP_VSCROLLBAR_VISIBLE,
   PROP_MOUSE_SCROLL,
+  PROP_OVERLAY_SCROLLBARS,
 };
 
 static void
@@ -148,6 +150,9 @@ st_scroll_view_get_property (GObject    *object,
     case PROP_MOUSE_SCROLL:
       g_value_set_boolean (value, priv->mouse_scroll);
       break;
+    case PROP_OVERLAY_SCROLLBARS:
+      g_value_set_boolean (value, priv->overlay_scrollbars);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
     }
@@ -212,6 +217,10 @@ st_scroll_view_set_property (GObject      *object,
       st_scroll_view_set_mouse_scrolling (self,
                                           g_value_get_boolean (value));
       break;
+    case PROP_OVERLAY_SCROLLBARS:
+      st_scroll_view_set_overlay_scrollbars (self,
+                                             g_value_get_boolean (value));
+      break;
     case PROP_HSCROLLBAR_POLICY:
       st_scroll_view_set_policy (self,
                                  g_value_get_enum (value),
@@ -376,14 +385,14 @@ st_scroll_view_get_preferred_width (ClutterActor *actor,
       account_for_vscrollbar = FALSE;
       break;
     case GTK_POLICY_ALWAYS:
-      account_for_vscrollbar = TRUE;
+      account_for_vscrollbar = !priv->overlay_scrollbars;
       break;
     case GTK_POLICY_AUTOMATIC:
       /* For automatic scrollbars, we always request space for the vertical
        * scrollbar; we won't know whether we actually need one until our
        * height is assigned in allocate().
        */
-      account_for_vscrollbar = TRUE;
+      account_for_vscrollbar = !priv->overlay_scrollbars;
       break;
     }
 
@@ -448,14 +457,14 @@ st_scroll_view_get_preferred_height (ClutterActor *actor,
       account_for_hscrollbar = FALSE;
       break;
     case GTK_POLICY_ALWAYS:
-      account_for_hscrollbar = TRUE;
+      account_for_hscrollbar = !priv->overlay_scrollbars;
       break;
     case GTK_POLICY_AUTOMATIC:
       /* For automatic scrollbars, we always request space for the horizontal
        * scrollbar; we won't know whether we actually need one until our
        * width is assigned in allocate().
        */
-      account_for_hscrollbar = TRUE;
+      account_for_hscrollbar = !priv->overlay_scrollbars;
       break;
     }
 
@@ -626,14 +635,15 @@ st_scroll_view_allocate (ClutterActor          *actor,
       clutter_actor_allocate (priv->hscroll, &child_box, flags);
     }
 
-  /* In case the scrollbar policy is NEVER, we don't trim the content
-   * box allocation by the scrollbar size.
+  /* In case the scrollbar policy is NEVER or scrollbars should be
+   * overlayed, we don't trim the content box allocation by the
+   * scrollbar size.
    * Fold this into the scrollbar sizes to simplify the rest of the
    * computations.
    */
-  if (priv->hscrollbar_policy == GTK_POLICY_NEVER)
+  if (priv->hscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars)
     sb_height = 0;
-  if (priv->vscrollbar_policy == GTK_POLICY_NEVER)
+  if (priv->vscrollbar_policy == GTK_POLICY_NEVER || priv->overlay_scrollbars)
     sb_width = 0;
 
   /* Child */
@@ -828,6 +838,14 @@ st_scroll_view_class_init (StScrollViewClass *klass)
                                    PROP_MOUSE_SCROLL,
                                    pspec);
 
+  pspec = g_param_spec_boolean ("overlay-scrollbars",
+                                "Use Overlay Scrollbars",
+                                "Overlay scrollbars over the content",
+                                FALSE,
+                                G_PARAM_READWRITE);
+  g_object_class_install_property (object_class,
+                                   PROP_OVERLAY_SCROLLBARS,
+                                   pspec);
 }
 
 static void
@@ -1090,6 +1108,49 @@ st_scroll_view_get_mouse_scrolling (StScrollView *scroll)
   return priv->mouse_scroll;
 }
 
+/**
+ * st_scroll_view_set_overlay_scrollbars:
+ * @scroll: A #StScrollView
+ * @enabled: Whether to enable overlay scrollbars
+ *
+ * Sets whether scrollbars are painted on top of the content.
+ */
+void
+st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
+                                       gboolean      enabled)
+{
+  StScrollViewPrivate *priv;
+
+  g_return_if_fail (ST_IS_SCROLL_VIEW (scroll));
+
+  priv = ST_SCROLL_VIEW (scroll)->priv;
+
+  if (priv->overlay_scrollbars != enabled)
+    {
+      priv->overlay_scrollbars = enabled;
+      g_object_notify (G_OBJECT (scroll), "overlay-scrollbars");
+      clutter_actor_queue_relayout (CLUTTER_ACTOR (scroll));
+    }
+}
+
+/**
+ * st_scroll_view_get_overlay_scrollbars:
+ * @scroll: A #StScrollView
+ *
+ * Gets the value set by st_scroll_view_set_overlay_scrollbars().
+ */
+gboolean
+st_scroll_view_get_overlay_scrollbars (StScrollView *scroll)
+{
+  StScrollViewPrivate *priv;
+
+  g_return_val_if_fail (ST_IS_SCROLL_VIEW (scroll), FALSE);
+
+  priv = ST_SCROLL_VIEW (scroll)->priv;
+
+  return priv->overlay_scrollbars;
+}
+
 /**
  * st_scroll_view_set_policy:
  * @scroll: A #StScrollView
index c00d16e2853482d74cd8e18ce15eea03f56c90f3..517e7dc214d5ae94e0444f8c0948c276e8a6c35c 100644 (file)
@@ -80,6 +80,10 @@ void          st_scroll_view_set_mouse_scrolling (StScrollView *scroll,
                                                   gboolean      enabled);
 gboolean      st_scroll_view_get_mouse_scrolling (StScrollView *scroll);
 
+void          st_scroll_view_set_overlay_scrollbars (StScrollView *scroll,
+                                                     gboolean      enabled);
+gboolean      st_scroll_view_get_overlay_scrollbars (StScrollView *scroll);
+
 void          st_scroll_view_set_policy          (StScrollView   *scroll,
                                                   GtkPolicyType   hscroll,
                                                   GtkPolicyType   vscroll);
index 967c9cdccce127928f7a560b9ef3eacdf2c9b4b5..26039d664791851b4af06fb57e3fd80842671d05 100644 (file)
@@ -339,6 +339,10 @@ function test() {
     let vfade = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' });
     fadeBox.add(vfade);
 
+    fadeBox.add(new St.Label({ text: 'Overlay scrollbars: '}));
+    let overlay = new St.Button({ label: 'No', style: 'text-decoration: underline; color: #4444ff;' });
+    fadeBox.add(overlay);
+
     function togglePadding(button) {
         switch(button.label) {
         case 'No':
@@ -388,6 +392,20 @@ function test() {
     vfade.connect('clicked', function() { toggleFade(vfade); });
     toggleFade(vfade);
 
+    function toggleOverlay(button) {
+        switch(button.label) {
+        case 'No':
+           button.label = 'Yes';
+           break;
+        case 'Yes':
+           button.label = 'No';
+           break;
+        }
+        scrollView.overlay_scrollbars = (button.label == 'Yes');
+    }
+
+    overlay.connect('clicked', function() { toggleOverlay(overlay); });
+
     UI.main(stage);
 }
 test();